package com.jing.cloud.service.group.helper;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.jing.cloud.service.group.bean.Group;
import com.jing.cloud.service.group.bean.GroupMember;
import com.jing.cloud.service.group.constant.GroupConstanct;
import com.jing.cloud.service.group.constant.GroupErrCode;
import com.jing.cloud.service.group.dao.GroupDao;
import com.jing.cloud.service.group.dao.GroupMemberDao;
import com.jing.cloud.service.util.db.Compare;
import com.jing.cloud.service.util.db.OrderBy;
import com.jing.cloud.service.util.db.Page;
import com.jing.cloud.service.Res;
import com.jing.cloud.util.RspUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by 29017 on 2017/9/19.
 */
@Component
public class GroupHelper {

    @Autowired
    private GroupDao groupDao;
    @Autowired
    private GroupMemberDao groupMemberDao;

    public Group getGroup(long groupId) {
        return groupDao.find(groupId);
    }

    public Res createGroup(Group group) {
        group.setId(null);
        Long owner = group.getCreateUserId();
        Preconditions.checkNotNull(owner, "creator is null");
        group.forCreate();
        groupDao.insert(group);
        Set<Long> ids = Sets.newHashSet();
        ids.add(group.getCreateUserId());
        addMember(group.getId(), ids, GroupConstanct.GROUP_LEVEL_OWNER);
        return RspUtil.success(group);
    }

    public Res addMember(long groupId, Set<Long> userIds, int level) {
        if (userIds.isEmpty()) {
            return RspUtil.error(GroupErrCode.GROUP_NONE_TO_ADD);
        }
        Map<String, Object> condition = Maps.newHashMap();
        condition.put("groupId", groupId);
        Compare userId = new Compare();
        userId.setIn(Lists.newArrayList(userIds));
        List<GroupMember> groupMembers = groupMemberDao.query(condition);
        Set<Long> member2Update = Sets.newHashSet();
        Set<Long> member2Insert = Sets.newHashSet();
        for (GroupMember groupMember : groupMembers) {
            Long uid = groupMember.getUserId();
            if (userIds.contains(uid)) {
                if (groupMember.deleted()) {
                    //逻辑删除的，要更新为非逻辑删除
                    member2Update.add(groupMember.getUserId());
                }
            } else {
                member2Insert.add(uid);
            }
        }
        if (!member2Insert.isEmpty()) {
            for (Long uid : member2Insert) {
                GroupMember gm = new GroupMember();
                gm.setGroupId(groupId);
                gm.setUserId(uid);
                gm.setLevel(level);
                gm.setRemarkName("");
                gm.forCreate();
                groupMemberDao.insert(gm);
            }
        }
        if (!member2Update.isEmpty()) {
            GroupMember gm = new GroupMember();
            gm.forUndelete();
            gm.setRemarkName("");
            Map<String, Object> cd = Maps.newHashMap();
            cd.put("groupId", groupId);
            Compare cUserId = new Compare();
            cUserId.setIn(Lists.newArrayList(member2Update));
            groupMemberDao.update(gm, cd);
            member2Insert.addAll(member2Update);
        }
        if (!member2Insert.isEmpty()) {
            // TODO: 2017/9/19  通知群变更
        } else {
            return RspUtil.error(GroupErrCode.GROUP_NONE_TO_ADD);
        }
        return RspUtil.success(member2Insert);
    }

    public Res removeMembers(long groupId, Set<Long> userIds) {
        if (userIds.isEmpty()) {
            return RspUtil.error(GroupErrCode.GROUP_NONE_TO_REMOVE);
        }
        Map<String, Object> condition = Maps.newHashMap();
        condition.put("groupId", groupId);
        Compare userId = new Compare();
        userId.setIn(Lists.newArrayList(userIds));
        List<GroupMember> groupMembers = groupMemberDao.query(condition);
        if (groupMembers.isEmpty()) {
            return RspUtil.error(GroupErrCode.GROUP_NONE_TO_REMOVE);
        }
        List<Long> member2delete = Lists.transform(groupMembers, new Function<GroupMember, Long>() {
            @Override
            public Long apply(GroupMember groupMember) {
                return groupMember.getUserId();
            }
        });
        GroupMember gm = new GroupMember();
        gm.setRemarkName("");
        gm.forDelete();
        userId.setIn(member2delete);
        groupMemberDao.update(gm, condition);
        return RspUtil.success(member2delete);
    }

    public List<Group> getGroupsByIds(List<Long> ids) {
        return groupDao.findByIds(ids);
    }

    public Page<GroupMember> getUserGroups(long userId, long ts, int size) {
        Map<String, Object> condition = Maps.newHashMap();
        condition.put("userId", userId);
        Compare cUpdatedAt = new Compare();
        cUpdatedAt.setGt(ts);
        condition.put("updatedAt", cUpdatedAt);
        Page<GroupMember> page = new Page<>();
        page.setPage(1);
        page.setPageSize(size);
        page.addOrderBy(new OrderBy("updatedAt", true));
        return groupMemberDao.query(condition, page);
    }

    public Page<GroupMember> getGroupMembers(long groupId, long ts, int size) {
        Map<String, Object> condition = Maps.newHashMap();
        condition.put("groupId", groupId);
        Compare cUpdatedAt = new Compare();
        cUpdatedAt.setGt(ts);
        condition.put("updatedAt", cUpdatedAt);
        Page<GroupMember> page = new Page<>();
        page.setPage(1);
        page.setPageSize(size);
        page.addOrderBy(new OrderBy("updatedAt", true));
        return groupMemberDao.query(condition, page);
    }

}
